/* 门面模式 */

/*
* 使用Api网关隐藏内部的服务细节，仅仅暴露最小的接口给客户端
*/

/// Api网关
pub struct ApiGateway {
    product_svc: ProductService,
    trade_svc: TradeService
}

impl ApiGateway {
    fn product_list(&self) -> Vec<String> {
        self.product_svc.product_list()
    }

    fn order(&self, product: &str) -> String {
        self.trade_svc.order(product)
    }
}

/// 商品服务
struct ProductService {}

impl ProductService {
    fn product_list(&self) -> Vec<String> {
        vec![
            String::from("苹果"),
            String::from("橘子"),
            String::from("香蕉")
        ]
    }
}

/// 交易服务
struct TradeService {}

impl TradeService {
    /// 下单，并且返回订单号
    fn order(&self, product: &str) -> String {
        println!("下单购买了 {}", product);
        format!("订单号 A001")
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn test_facade_1() {
        let product_svc = ProductService{};
        let trade_svc = TradeService{};
        let api = ApiGateway{product_svc, trade_svc};

        let product_list = api.product_list();
        assert_eq!(vec![
            String::from("苹果"),
            String::from("橘子"),
            String::from("香蕉")
        ], product_list);
    }

    #[test]
    fn test_facade_2() {
        let product_svc = ProductService{};
        let trade_svc = TradeService{};
        let api = ApiGateway{product_svc, trade_svc};

        let trade_no = api.order(&String::from("橘子"));
        assert_eq!(String::from("订单号 A001"), trade_no);
    }
}